package com.wdcloud.netlibrary.request;

import android.os.Handler;

import com.wdcloud.netlibrary.callback.DownloadProgressCallback;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

/**
 *
 */
public class MultiRequest extends BaseRequest<MultiRequest> {

    private List<Mapper<String, String, String>> files;

    /**
     * 添加文件
     *
     */
    public MultiRequest addFile(Mapper<String, String, String> mapper) {
        if (files == null) {
            files = new ArrayList<>();
        }
        files.add(mapper);
        return this;
    }

    public MultiRequest addFile(List<Mapper<String, String, String>> mapper) {
        if (files == null) {
            files = new ArrayList<>();
        }
        files.addAll(mapper);
        return this;
    }

    @Override
    protected void buildRequest() {
        if (url == null) {
            throw new RuntimeException("请求路径不能为空");
        }

        MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
        bodyBuilder.setType(MultipartBody.FORM);
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (null == entry.getValue()) {
                    bodyBuilder.addFormDataPart(entry.getKey(), "");
                } else {
                    bodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
                }
            }
        }

        if (files != null) {
            for (Mapper<String, String, String> mapper : files) {
                String key = mapper.k;
                String mimeType = mapper.v;
                String filePath = mapper.m;
                File file = new File(filePath);
                if (!file.exists()) {
                    throw new RuntimeException("文件路径错误");
                }
                if (!file.isFile()) {
                    throw new RuntimeException("必须为具体文件");
                }
                bodyBuilder.addFormDataPart(key, file.getName(), RequestBody.create(MediaType.parse(mimeType), file));
            }
        }
        builder.url(url).post(bodyBuilder.build());
    }


    /**
     * 上传进度监听
     *
     * @param handler     Handler
     * @param contentType MediaType
     * @param file        文件
     * @param listener    回调
     */
    private static RequestBody createCustomRequestBody(final Handler handler, final MediaType contentType,
                                                       final File file, final DownloadProgressCallback listener) {
        return new RequestBody() {
            long totalBytesRead = 0;
            long lastUpdate = 0;

            @Override
            public MediaType contentType() {
                return contentType;
            }

            @Override
            public long contentLength() {
                return file.length();
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                Source source;
                try {
                    source = Okio.source(file);
                    Buffer buf = new Buffer();
                    for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
                        sink.write(buf, readCount);
                        totalBytesRead += readCount;
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (totalBytesRead == lastUpdate) {
                                    return;
                                }
                                listener.onProgress(totalBytesRead, contentLength(), totalBytesRead);
                                lastUpdate = totalBytesRead;
                            }
                        });
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }

}
